from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.http import JsonResponse
from django.db.models import Q, Max
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from django.utils import timezone
import json

from .models import Follow, Message, Conversation, Friendship, Group, GroupMembership, GroupMessage, SystemNotification
from users.models import User
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
from .redis_utils import chat_redis


@login_required
def follow_user(request, user_id):
    """关注用户"""
    user_to_follow = get_object_or_404(User, id=user_id)
    
    if user_to_follow == request.user:
        return JsonResponse({'success': False, 'message': '不能关注自己'})
    
    follow, created = Follow.objects.get_or_create(
        follower=request.user,
        following=user_to_follow
    )
    
    if created:
        return JsonResponse({'success': True, 'message': '关注成功', 'action': 'followed'})
    else:
        return JsonResponse({'success': False, 'message': '已经关注过了'})


@login_required
def unfollow_user(request, user_id):
    """取消关注"""
    user_to_unfollow = get_object_or_404(User, id=user_id)
    
    try:
        follow = Follow.objects.get(
            follower=request.user,
            following=user_to_unfollow
        )
        follow.delete()
        return JsonResponse({'success': True, 'message': '已取消关注', 'action': 'unfollowed'})
    except Follow.DoesNotExist:
        return JsonResponse({'success': False, 'message': '未关注该用户'})


@login_required
def followers_list(request):
    """粉丝列表"""
    followers = Follow.objects.filter(following=request.user).select_related('follower')
    context = {'followers': followers}
    return render(request, 'social/followers_list.html', context)


@login_required
def following_list(request):
    """关注列表"""
    following = Follow.objects.filter(follower=request.user).select_related('following')
    context = {'following': following}
    return render(request, 'social/following_list.html', context)


@login_required
def user_list(request):
    """用户列表 - 用于开始新对话"""
    # 获取除当前用户外的所有用户
    users = User.objects.exclude(id=request.user.id).order_by('-created_at')
    context = {'users': users}
    return render(request, 'social/user_list.html', context)


# 旧的视图函数已删除，使用chat_main和chat_content替代


@login_required
@require_http_methods(["POST"])
def start_conversation(request, user_id):
    """开始会话 - API版本"""
    other_user = get_object_or_404(User, id=user_id)
    
    if other_user == request.user:
        return JsonResponse({'success': False, 'message': '不能与自己聊天'})
    
    # 查找现有会话
    conversation = Conversation.objects.filter(
        participants=request.user
    ).filter(
        participants=other_user
    ).distinct().first()
    
    # 如果没有找到会话，创建新的
    if not conversation:
        conversation = Conversation.objects.create()
        conversation.participants.add(request.user, other_user)
    
    return JsonResponse({
        'success': True,
        'conversation_id': conversation.id,
        'message': '会话已创建'
    })


@login_required
@require_http_methods(["POST"])
def send_message_api(request, conversation_id):
    """发送消息API"""
    conversation = get_object_or_404(Conversation, id=conversation_id, participants=request.user)
    
    try:
        data = json.loads(request.body)
        content = data.get('content', '').strip()
        
        if not content:
            return JsonResponse({'success': False, 'message': '消息内容不能为空'})
        
        # 创建消息
        message = Message.objects.create(
            conversation=conversation,
            sender=request.user,
            content=content,
            message_type='text'
        )
        
        # 保存消息到Redis
        message_data = {
            'id': message.id,
            'content': message.content,
            'sender_id': request.user.id,
            'sender_username': request.user.username,
            'sender_nickname': request.user.nickname or request.user.username,
            'sender_avatar': request.user.avatar.url if request.user.avatar else None,
            'created_at': message.created_at.isoformat(),
            'message_type': message.message_type,
            'is_read': False,
        }
        chat_redis.save_message(conversation_id, message_data)
        
        # 更新会话时间
        conversation.updated_at = timezone.now()
        conversation.save()
        
        # 通过WebSocket发送实时消息
        channel_layer = get_channel_layer()
        async_to_sync(channel_layer.group_send)(
            f'chat_{conversation_id}',
            {
                'type': 'chat_message',
                'message': {
                    'id': message.id,
                    'content': message.content,
                    'sender_id': request.user.id,
                    'sender': {
                        'id': request.user.id,
                        'username': request.user.username,
                        'nickname': request.user.nickname or request.user.username,
                        'avatar': request.user.avatar.url if request.user.avatar else None,
                    },
                    'created_at': message.created_at.isoformat(),
                    'message_type': message.message_type,
                }
            }
        )
        
        # 发送通知给其他用户
        other_user = conversation.get_other_participant(request.user)
        async_to_sync(channel_layer.group_send)(
            f'notifications_{other_user.id}',
            {
                'type': 'send_message_notification',
                'message': {
                    'id': message.id,
                    'content': message.content,
                    'sender': {
                        'id': request.user.id,
                        'username': request.user.username,
                        'nickname': request.user.nickname or request.user.username,
                        'avatar': request.user.avatar.url if request.user.avatar else None,
                    },
                    'conversation_id': conversation_id,
                    'created_at': message.created_at.isoformat(),
                }
            }
        )
        
        return JsonResponse({
            'success': True,
            'message': {
                'id': message.id,
                'content': message.content,
                'created_at': message.created_at.isoformat(),
            }
        })
        
    except json.JSONDecodeError:
        return JsonResponse({'success': False, 'message': '无效的JSON数据'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})


@login_required
@require_http_methods(["POST"])
def mark_messages_read(request, conversation_id):
    """标记消息为已读"""
    conversation = get_object_or_404(Conversation, id=conversation_id, participants=request.user)
    
    try:
        data = json.loads(request.body)
        message_ids = data.get('message_ids', [])
        
        # 标记消息为已读
        conversation.messages.filter(
            id__in=message_ids,
            sender=conversation.get_other_participant(request.user)
        ).update(is_read=True)
        
        return JsonResponse({'success': True})
        
    except json.JSONDecodeError:
        return JsonResponse({'success': False, 'message': '无效的JSON数据'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})


@login_required
def get_conversation_messages(request, conversation_id):
    """获取会话消息"""
    conversation = get_object_or_404(Conversation, id=conversation_id, participants=request.user)
    
    # 先从Redis获取消息
    messages_data = chat_redis.get_messages(conversation_id, limit=100)
    
    # 如果Redis中没有消息，从数据库获取并同步到Redis
    if not messages_data:
        messages = conversation.messages.all().order_by('created_at')
        
        for message in messages:
            message_data = {
                'id': message.id,
                'content': message.content,
                'sender_id': message.sender.id,
                'sender_username': message.sender.username,
                'sender_nickname': message.sender.nickname or message.sender.username,
                'sender_avatar': message.sender.avatar.url if message.sender.avatar else None,
                'created_at': message.created_at.isoformat(),
                'message_type': message.message_type,
                'is_read': message.is_read,
            }
            messages_data.append(message_data)
            # 同步到Redis
            chat_redis.save_message(conversation_id, message_data)
    
    return JsonResponse({
        'success': True,
        'messages': messages_data
    })


@login_required
def chat_main(request):
    """聊天主页面 - 左侧显示会话列表、好友和群组，右侧显示聊天内容"""
    try:
        # 检查用户认证
        if not request.user.is_authenticated:
            messages.error(request, '请先登录')
            return redirect('users:login')

        # 获取用户参与的所有会话
        conversations = Conversation.objects.filter(participants=request.user).prefetch_related('participants',
                                                                                                'messages')

        # 构建会话列表数据
        conversation_list = []
        for conversation in conversations:
            try:
                other_user = conversation.get_other_participant(request.user)

                # 检查 other_user 是否存在
                if other_user is None:
                    print(f"警告: 会话 {conversation.id} 中找不到其他参与者")
                    continue  # 跳过这个会话

                # 安全地访问用户属性
                avatar_url = None
                if other_user.avatar:
                    try:
                        avatar_url = other_user.avatar.url
                    except Exception as e:
                        print(f"获取用户头像错误: {str(e)}")

                # 先从Redis获取最后一条消息
                last_message = chat_redis.get_latest_message(conversation.id)

                # 如果Redis中没有，从数据库获取
                if not last_message:
                    db_last_message = conversation.get_last_message()
                    if db_last_message:
                        last_message = {
                            'content': db_last_message.content,
                            'created_at': db_last_message.created_at.isoformat(),
                        }

                # 计算未读消息数（从数据库）
                unread_count = conversation.messages.filter(
                    sender=other_user,
                    is_read=False
                ).count()

                conversation_list.append({
                    'conversation_id': conversation.id,
                    'type': 'conversation',
                    'other_user': {
                        'id': other_user.id,
                        'username': other_user.username,
                        'nickname': other_user.nickname or other_user.username,
                        'avatar': avatar_url,
                    },
                    'last_message': last_message or {},
                    'unread_count': unread_count,
                })

            except Exception as e:
                print(f"处理会话 {conversation.id} 时出错: {str(e)}")
                continue  # 跳过有问题的会话

        # 获取好友列表
        friends_list = []
        try:
            friends = Friendship.get_friends(request.user)
            for friend in friends:
                if friend is None:
                    continue

                # 安全地访问好友属性
                avatar_url = None
                if friend.avatar:
                    try:
                        avatar_url = friend.avatar.url
                    except Exception as e:
                        print(f"获取好友头像错误: {str(e)}")

                # 检查是否有会话
                conversation = Conversation.objects.filter(
                    participants=request.user
                ).filter(
                    participants=friend
                ).first()

                friends_list.append({
                    'id': friend.id,
                    'username': friend.username,
                    'nickname': friend.nickname or friend.username,
                    'avatar': avatar_url,
                    'has_conversation': conversation is not None,
                    'conversation_id': conversation.id if conversation else None,
                })
        except Exception as e:
            print(f"获取好友列表错误: {str(e)}")

        # 获取群组列表
        groups_list = []
        try:
            groups = request.user.joined_groups.all().prefetch_related('memberships')
            for group in groups:
                # 安全地访问群组属性
                avatar_url = None
                if group.avatar:
                    try:
                        avatar_url = group.avatar.url
                    except Exception as e:
                        print(f"获取群组头像错误: {str(e)}")

                # 获取最后一条消息
                last_message = chat_redis.get_latest_message(f'group_{group.id}')

                if not last_message:
                    db_last_message = group.get_last_message()
                    if db_last_message:
                        last_message = {
                            'content': db_last_message.content,
                            'created_at': db_last_message.created_at.isoformat(),
                        }

                groups_list.append({
                    'id': group.id,
                    'type': 'group',
                    'name': group.name,
                    'description': group.description,
                    'avatar': avatar_url,
                    'member_count': group.memberships.count(),
                    'last_message': last_message or {},
                })
        except Exception as e:
            print(f"获取群组列表错误: {str(e)}")

        # 按最后消息时间排序
        conversation_list.sort(
            key=lambda x: x['last_message'].get('created_at', '') if x['last_message'] else '',
            reverse=True
        )

        context = {
            'conversations': conversation_list,
            'friends': friends_list,
            'groups': groups_list,
        }
        return render(request, 'social/chat_main.html', context)

    except Exception as e:
        print(f"聊天主页面错误: {str(e)}")
        import traceback
        traceback.print_exc()

        messages.error(request, '加载聊天页面时出现错误')

        # 返回空数据的上下文，避免页面完全崩溃
        context = {
            'conversations': [],
            'friends': [],
            'groups': [],
        }
        return render(request, 'social/chat_main.html', context)


@login_required
def chat_content(request, conversation_id):
    """获取聊天内容（AJAX）"""
    conversation = get_object_or_404(Conversation, id=conversation_id, participants=request.user)
    other_user = conversation.get_other_participant(request.user)
    
    # 从Redis获取消息
    messages = chat_redis.get_messages(conversation_id, limit=100)
    
    # 如果Redis中没有消息，从数据库获取并同步到Redis
    if not messages:
        db_messages = conversation.messages.all().order_by('created_at')
        
        for message in db_messages:
            message_data = {
                'id': message.id,
                'content': message.content,
                'sender_id': message.sender.id,
                'sender_username': message.sender.username,
                'sender_nickname': message.sender.nickname or message.sender.username,
                'sender_avatar': message.sender.avatar.url if message.sender.avatar else None,
                'created_at': message.created_at.isoformat(),
                'message_type': message.message_type,
                'is_read': message.is_read,
            }
            messages.append(message_data)
            # 同步到Redis
            chat_redis.save_message(conversation_id, message_data)
    
    # 标记消息为已读
    conversation.messages.filter(
        sender=other_user,
        is_read=False
    ).update(is_read=True)
    
    return JsonResponse({
        'success': True,
        'other_user': {
            'id': other_user.id,
            'username': other_user.username,
            'nickname': other_user.nickname or other_user.username,
            'avatar': other_user.avatar.url if other_user.avatar else None,
        },
        'messages': messages
    })


@login_required
def get_conversations_list(request):
    """获取会话列表（AJAX）"""
    # 获取用户参与的所有会话
    conversations = Conversation.objects.filter(participants=request.user).prefetch_related('participants', 'messages')
    
    # 构建会话列表数据
    conversation_list = []
    for conversation in conversations:
        other_user = conversation.get_other_participant(request.user)
        
        # 先从Redis获取最后一条消息
        last_message = chat_redis.get_latest_message(conversation.id)
        
        # 如果Redis中没有，从数据库获取
        if not last_message:
            db_last_message = conversation.get_last_message()
            if db_last_message:
                last_message = {
                    'content': db_last_message.content,
                    'created_at': db_last_message.created_at.isoformat(),
                }
        
        # 计算未读消息数（从数据库）
        unread_count = conversation.messages.filter(
            sender=other_user,
            is_read=False
        ).count()
        
        conversation_list.append({
            'conversation_id': conversation.id,
            'type': 'conversation',
            'other_user': {
                'id': other_user.id,
                'username': other_user.username,
                'nickname': other_user.nickname or other_user.username,
                'avatar': other_user.avatar.url if other_user.avatar else None,
            },
            'last_message': last_message,
            'unread_count': unread_count,
        })
    
    # 按最后消息时间排序
    conversation_list.sort(
        key=lambda x: x['last_message']['created_at'] if x['last_message'] else '',
        reverse=True
    )
    
    return JsonResponse({
        'success': True,
        'conversations': conversation_list
    })


#获取系统通知列表
@login_required
def notifications_list(request):
    """获取系统通知列表"""
    try:
        notifications = SystemNotification.objects.filter(user=request.user).order_by('-created_at')

        notifications_data = []
        for notification in notifications:
            notifications_data.append({
                'id': notification.id,
                'title': notification.title,
                'content': notification.content,
                'notification_type': notification.notification_type,
                'is_read': notification.is_read,
                'created_at': notification.created_at.isoformat(),
                'admin_user': notification.admin_user.username if notification.admin_user else None,
                'related_activity': {
                    'id': notification.related_activity.id,
                    'title': notification.related_activity.title
                } if notification.related_activity else None
            })

        return JsonResponse({
            'success': True,
            'notifications': notifications_data,
            'count': len(notifications_data)
        })
    except Exception as e:
        print(f"获取通知列表时出错: {str(e)}")
        return JsonResponse({
            'success': False,
            'message': '获取通知失败',
            'notifications': []
        })


@login_required
@require_http_methods(["DELETE"])
def delete_all_notifications(request):
    """删除当前用户的全部系统通知"""
    try:
        # 删除当前用户的所有系统通知
        deleted_count, _ = SystemNotification.objects.filter(user=request.user).delete()

        return JsonResponse({
            'success': True,
            'message': f'成功删除 {deleted_count} 条系统消息',
            'deleted_count': deleted_count
        })
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'删除失败: {str(e)}'
        }, status=500)
@login_required
@require_http_methods(["POST"])
def mark_notification_read(request, notification_id):
    """标记单个通知为已读"""
    try:
        notification = SystemNotification.objects.get(id=notification_id, user=request.user)
        notification.is_read = True
        notification.save()

        return JsonResponse({'success': True, 'message': '通知已标记为已读'})
    except SystemNotification.DoesNotExist:
        return JsonResponse({'success': False, 'message': '通知不存在'})
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})


@login_required
@require_http_methods(["POST"])
def mark_all_notifications_read(request):
    """标记所有通知为已读"""
    try:
        # 将用户的所有未读通知标记为已读
        updated_count = SystemNotification.objects.filter(
            user=request.user,
            is_read=False
        ).update(is_read=True)

        return JsonResponse({
            'success': True,
            'message': f'已标记 {updated_count} 条通知为已读'
        })
    except Exception as e:
        return JsonResponse({'success': False, 'message': str(e)})


@login_required
def get_unread_counts(request):
    """获取未读消息、好友请求、群组消息和系统通知的数量"""
    try:
        # 未读私信数量
        unread_messages = Message.objects.filter(
            conversation__participants=request.user,
            is_read=False
        ).exclude(sender=request.user).count()
        
        # 待处理的好友请求数量
        friend_requests = Friendship.objects.filter(
            to_user=request.user,
            status='pending'
        ).count()
        
        # 未读群组消息数量（这里简化处理，可以根据需要优化）
        # 获取用户加入的所有群组
        user_groups = request.user.joined_groups.all()
        unread_group_messages = 0
        
        # 未读系统通知数量
        unread_notifications = SystemNotification.objects.filter(
            user=request.user,
            is_read=False
        ).count()
        
        return JsonResponse({
            'success': True,
            'unread_messages': unread_messages,
            'friend_requests': friend_requests,
            'unread_group_messages': unread_group_messages,
            'unread_notifications': unread_notifications,
            'total': unread_messages + friend_requests + unread_group_messages + unread_notifications
        })
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': str(e)
        })


@login_required
@require_http_methods(["POST"])
def delete_conversation(request, conversation_id):
    """删除会话及其所有消息"""
    conversation = get_object_or_404(Conversation, id=conversation_id, participants=request.user)
    
    try:
        # 删除会话（会级联删除所有消息）
        conversation.delete()
        
        # 从Redis中删除消息
        chat_redis.redis_client.delete(f'conversation:{conversation_id}:messages')
        
        return JsonResponse({
            'success': True,
            'message': '聊天记录已删除'
        })
    except Exception as e:
        return JsonResponse({
            'success': False,
            'message': f'删除失败: {str(e)}'
        })


